package com.qen.repository;

import com.qen.common.BeetlUtils;
import com.qen.common.GenericTypeUtils;
import com.qen.wrapper.Wrapper;
import com.qen.wrapper.Wrappers;
import org.beetl.sql.clazz.kit.BeetlSQLException;
import org.beetl.sql.core.page.PageRequest;
import org.beetl.sql.core.page.PageResult;

import java.util.List;
import java.util.Map;

/**
 * Lamdba Dao
 *
 * @author licz
 * @data 2025年05月14日 3:13 PM
 */
public interface LambdaDao<T> extends LambdaHandDao<T> {

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap 表字段 map 对象
     */
    default List<T> selectByMap(Map<String, Object> columnMap) {
        return this.selectList(Wrappers.<T>query().allEq(columnMap));
    }

    /**
     * 根据 entity 条件，查询一条记录
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default T selectOne(Wrapper<T> queryWrapper) {
        return this.selectOne(queryWrapper, true);
    }

    /**
     * 根据 entity 条件，查询一条记录，现在会根据{@code throwEx}参数判断是否抛出异常，如果为false就直接返回一条数据
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param throwEx      boolean 参数，为true如果存在多个结果直接抛出异常
     */
    default T selectOne(Wrapper<T> queryWrapper, boolean throwEx) {
        List<T> list = this.selectList(queryWrapper);
        int size = list.size();
        if (size == 1) {
            return list.get(0);
        } else if (size > 1) {
            if (throwEx) {
                throw new BeetlSQLException(BeetlSQLException.ID_EXPECTED_ONE_ERROR, "查询期望只返回一条结果集，但返回了" + size + "条");
            }
            return list.get(0);
        }
        return null;
    }

    /**
     * 根据 Wrapper 条件，判断是否存在记录
     *
     * @param queryWrapper 实体对象封装操作类
     * @return 是否存在记录
     */
    default boolean exists(Wrapper<T> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0;
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default Long selectCount(Wrapper<T> queryWrapper) {
        Class clz = GenericTypeUtils.getGenericType(getClass().getGenericSuperclass());
        return selectCount(queryWrapper, clz);
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     *
     * @param clz          查哪个表
     * @param <E>          被查的POJO表名
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    <E> Long selectCount(Wrapper<T> queryWrapper, Class<E> clz);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default List<T> selectList(Wrapper<T> queryWrapper) {
        Class clz = GenericTypeUtils.getGenericType(getClass().getGenericSuperclass());
        return selectObjs(queryWrapper, clz);
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @since 1.0.0
     */
    <E, P extends PageRequest<E>> PageResult<E> selectList(P page, Wrapper<T> queryWrapper, Class<E> clz);

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @since 1.0.0
     */
    default PageResult<T> selectList(PageRequest<T> page, Wrapper<T> queryWrapper) {
        Class clz = GenericTypeUtils.getGenericType(getClass().getGenericSuperclass());
        return selectList(page, queryWrapper, clz);
    }


    /**
     * 根据 Wrapper 条件，查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类
     */
    default List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper) {
        List<Map> list = selectList(null, queryWrapper, Map.class).getList();
        return BeetlUtils.convertResult(list);
    }


    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     * @since 1.0.0
     */
    default <P extends PageRequest<Map>> List<Map<String, Object>> selectMaps(P page, Wrapper<T> queryWrapper) {
        List<Map> list = selectList(page, queryWrapper, Map.class).getList();
        return BeetlUtils.convertResult(list);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     * <p>注意： 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default <E> List<E> selectObjs(Wrapper<T> queryWrapper, Class<E> clz) {
        return selectList(null, queryWrapper, clz).getList();
    }

    /**
     * 根据 Wrapper 条件，查询全部记录
     * <p>注意： 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default List<T> selectObjs(Wrapper<T> queryWrapper) {
        return selectList(null, queryWrapper).getList();
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default <P extends PageRequest<T>> PageResult<T> selectPage(P page, Wrapper<T> queryWrapper) {
        return selectList(page, queryWrapper);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    default <P extends PageRequest<Map>> PageResult<Map> selectMapsPage(P page, Wrapper<T> queryWrapper) {
        return selectList(page, queryWrapper, Map.class);
    }

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default <P extends PageRequest<T>> PageResult<T> selectPage(P page, Wrapper<T> queryWrapper, boolean isTotal) {
        return selectList(page, queryWrapper);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    default <P extends PageRequest<Map>> PageResult<Map> selectMapsPage(P page, Wrapper<T> queryWrapper, boolean isTotal) {
        return selectList(page, queryWrapper, Map.class);
    }

}
